package com.cs.vessel.breakdown.view;

import java.util.UUID;

import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.part.ViewPart;

import com.cs.vessel.breakdown.Activator;
import com.cs.vessel.breakdown.CDOHibernateUtil;
import com.cs.vessel.breakdown.Messages;
import com.sc.vessel.info.model.breakdown.AttributeIdentify;
import com.sc.vessel.info.model.breakdown.BreakdownFactory;
import com.sc.vessel.info.model.breakdown.ConfigElement;
import com.sc.vessel.info.model.breakdown.Configuration;

public class ConfigurationView extends ViewPart {

    public static final String ID = "com.cs.vessel.breakdown.configurationView"; //$NON-NLS-1$

    private TreeViewer viewer;

    private Configuration configuration;

    private Action createConfigElement;

    private Action editConfigElement;

    private Action createAttributeIdentify;

    private Action editAttributeIdentify;

    private IAction refreshAllAction;

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        viewer.setContentProvider(new ViewContentProvider());
        viewer.setLabelProvider(new ViewLabelProvider());
        viewer.setInput(""); //$NON-NLS-1$
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection selection = ((IStructuredSelection) event.getSelection());
                Object obj = selection.getFirstElement();
                updateOKStatus(obj, selection.toArray().length);
            }
        });
        makeActions();
        hookContextMenu();
        contributeToActionBars();
    }

    /**
     * DOC liaoqc Comment method "updateOKStatus".
     * 
     * @param obj
     * @param length
     */
    protected void updateOKStatus(Object obj, int length) {
        if (length == 0) {
            createConfigElement.setEnabled(true);
            createAttributeIdentify.setEnabled(false);
        } else if (length > 1) {
            createConfigElement.setEnabled(false);
            createAttributeIdentify.setEnabled(false);
        } else {
            if (obj instanceof ConfigElement) {
                createConfigElement.setEnabled(true);
                createAttributeIdentify.setEnabled(true);
            } else if (obj instanceof AttributeIdentify) {
                createConfigElement.setEnabled(true);
                createAttributeIdentify.setEnabled(false);
            }
        }

    }

    /**
     * DOC liaoqc Comment method "hookContextMenu".
     */
    private void hookContextMenu() {
        MenuManager mgr = new MenuManager();
        mgr.setRemoveAllWhenShown(true);
        mgr.addMenuListener(new IMenuListener() {

            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }
        });
        Menu menu = mgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(mgr, viewer);
    }

    /**
     * DOC liaoqc Comment method "fillContextMenu".
     * 
     * @param manager
     */
    protected void fillContextMenu(IMenuManager manager) {
        manager.add(createConfigElement);
        manager.add(createAttributeIdentify);
        manager.add(new Separator());
        manager.add(editConfigElement);
        manager.add(editAttributeIdentify);
        manager.add(new Separator());
        manager.add(refreshAllAction);
    }

    /**
     * DOC liaoqc Comment method "makeActions".
     */
    private void makeActions() {
        createConfigElement = new Action() {

            public void run() {
                InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.ConfigurationView_0,
                        Messages.ConfigurationView_1, "", //$NON-NLS-3$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$
                        new IInputValidator() {

                            @Override
                            public String isValid(String newText) {
                                if (newText == null || "".equals(newText)) { //$NON-NLS-1$
                                    return Messages.NavigationView_5;
                                }
                                return null;
                            }
                        });
                inputDialog.open();
                String newName = inputDialog.getValue();
                if (newName == null || "".equals(newName)) { //$NON-NLS-1$
                    return;
                }
                // added configElement
                ConfigElement configElement = BreakdownFactory.eINSTANCE.createConfigElement();
                configElement.setName(newName);
                String itemId = UUID.randomUUID().toString();
                configElement.setItemId(itemId);
                try {
                    CDOHibernateUtil.addConfigElement(configElement);
                } catch (CommitException e) {
                    // added failed
                    e.printStackTrace();
                }
                viewer.refresh();
            }
        };

        createConfigElement.setText(Messages.ConfigurationView_6);
        createConfigElement.setToolTipText(Messages.ConfigurationView_7);
        createConfigElement.setImageDescriptor(Activator.getImageDescriptor("/icons/config_element.gif")); //$NON-NLS-1$

        createAttributeIdentify = new Action() {

            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.ConfigurationView_4,
                        Messages.ConfigurationView_13, "", new IInputValidator() { //$NON-NLS-1$

                            @Override
                            public String isValid(String newText) {
                                if (newText == null || "".equals(newText)) { //$NON-NLS-1$
                                    return Messages.NavigationView_5;
                                }
                                return null;
                            }
                        });
                inputDialog.open();
                String newName = inputDialog.getValue();
                if (newName == null || "".equals(newName)) { //$NON-NLS-1$
                    return;
                }
                if (obj instanceof ConfigElement) {
                    ConfigElement configElement = (ConfigElement) obj;
                    // obj must be ConfigElement
                    // add attributeIdentify
                    AttributeIdentify attributeIdentify = BreakdownFactory.eINSTANCE.createAttributeIdentify();
                    attributeIdentify.setName(newName);
                    attributeIdentify.setItemId(UUID.randomUUID().toString());
                    try {
                        CDOHibernateUtil.addAttributeIdentify(configElement, attributeIdentify);
                    } catch (CommitException e) {
                        // added failed
                        e.printStackTrace();
                    }
                    viewer.refresh(configElement);
                }
            }
        };

        createAttributeIdentify.setText(Messages.ConfigurationView_5);
        createAttributeIdentify.setToolTipText(Messages.ConfigurationView_8);
        createAttributeIdentify.setImageDescriptor(Activator.getImageDescriptor("/icons/attribute_identify.gif")); //$NON-NLS-1$

        refreshAllAction = new Action() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.action.Action#run()
             */
            @Override
            public void run() {
                viewer.refresh();
            }
        };
        refreshAllAction.setText(Messages.ConfigurationView_9);
        refreshAllAction.setToolTipText(Messages.ConfigurationView_11);
        refreshAllAction.setImageDescriptor(Activator.getImageDescriptor("/icons/refresh_blue.gif")); //$NON-NLS-1$

        editConfigElement = new Action() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.action.Action#run()
             */
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                if (obj instanceof ConfigElement) {
                    ConfigElement configElement = (ConfigElement) obj;
                    InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.ConfigurationView_3,
                            Messages.ConfigurationView_12, configElement.getName(), new IInputValidator() { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$

                                @Override
                                public String isValid(String newText) {
                                    if (newText == null || "".equals(newText)) { //$NON-NLS-1$
                                        return Messages.NavigationView_5;
                                    }
                                    return null;
                                }
                            });
                    inputDialog.open();
                    String newName = inputDialog.getValue();
                    if (newName == null || "".equals(newName) || configElement.getName().equals(newName)) { //$NON-NLS-1$
                        return;
                    }
                    try {
                        CDOHibernateUtil.editConfigElementName(configElement, newName);
                    } catch (CommitException e) {
                        // add failed log
                        e.printStackTrace();
                    }
                    viewer.refresh();
                }
            }

        };

        editConfigElement.setText(Messages.ConfigurationView_14);
        editConfigElement.setToolTipText(Messages.ConfigurationView_15);
        editConfigElement.setImageDescriptor(Activator.getImageDescriptor("/icons/config_element.gif")); //$NON-NLS-1$

        editAttributeIdentify = new Action() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.action.Action#run()
             */
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                if (obj instanceof AttributeIdentify) {
                    AttributeIdentify attributeIdentify = (AttributeIdentify) obj;
                    InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.ConfigurationView_16,
                            Messages.ConfigurationView_17, attributeIdentify.getName(), new IInputValidator() { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$

                                @Override
                                public String isValid(String newText) {
                                    if (newText == null || "".equals(newText)) { //$NON-NLS-1$
                                        return Messages.NavigationView_5;
                                    }
                                    return null;
                                }
                            });
                    inputDialog.open();
                    String newName = inputDialog.getValue();
                    if (newName == null || "".equals(newName) || attributeIdentify.getName().equals(newName)) { //$NON-NLS-1$
                        return;
                    }
                    try {
                        CDOHibernateUtil.editValueIdentifyName(attributeIdentify, newName);
                    } catch (CommitException e) {
                        // add failed log
                        e.printStackTrace();
                    }
                    viewer.refresh();
                }
            }

        };

        editAttributeIdentify.setText(Messages.ConfigurationView_19);
        editAttributeIdentify.setToolTipText(Messages.ConfigurationView_20);
        editAttributeIdentify.setImageDescriptor(Activator.getImageDescriptor("/icons/attribute_identify.gif")); //$NON-NLS-1$

    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalToolBar(IToolBarManager manager) {
        manager.add(refreshAllAction);
    }

    class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {

        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        }

        public void dispose() {
        }

        public Object[] getElements(Object parent) {
            ConfigurationView.this.configuration = CDOHibernateUtil.getConfiguration();
            return configuration.getElements().toArray();
        }

        public Object getParent(Object child) {
            return null;
        }

        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof ConfigElement) {
                ConfigElement configElement = (ConfigElement) parentElement;
                return configElement.getAttributeIdentifies().toArray();
            }
            return null;
        }

        public boolean hasChildren(Object parent) {
            if (parent instanceof ConfigElement) {
                ConfigElement component = (ConfigElement) parent;
                if (component.getAttributeIdentifies().size() != 0) {
                    return true;
                }
            }
            return false;
        }
    }

    class ViewLabelProvider extends LabelProvider {

        public String getText(Object obj) {
            if (obj instanceof ConfigElement) {
                ConfigElement configElement = (ConfigElement) obj;
                return configElement.getName();
            }
            if (obj instanceof AttributeIdentify) {
                AttributeIdentify attributeIdentify = (AttributeIdentify) obj;
                return attributeIdentify.getName();

            }
            return obj.toString();
        }

        public Image getImage(Object obj) {
            if (obj instanceof ConfigElement) {
                return Activator.getImageDescriptor("/icons/config_element.gif").createImage(); //$NON-NLS-1$
            }
            return Activator.getImageDescriptor("/icons/attribute_identify.gif").createImage(); //$NON-NLS-1$
        }
    }

    @Override
    public void setFocus() {
        // TODO Auto-generated method stub

    }

}
